package net.lesscoding.server;

import io.netty.bootstrap.ServerBootstrap;
import io.netty.buffer.ByteBuf;
import io.netty.channel.*;
import io.netty.channel.nio.NioEventLoopGroup;
import io.netty.channel.socket.nio.NioServerSocketChannel;
import io.netty.channel.socket.nio.NioSocketChannel;
import lombok.extern.slf4j.Slf4j;
import net.lesscoding.Const;

import java.nio.charset.StandardCharsets;

/**
 * @author eleven
 * @date 2024/10/23 16:26
 * @apiNote
 */
@Slf4j
public class EventLoopServerTest {
    /**
     * 事件循环组服务端测试
     *
     * 1. 在添加 group 的时候 细分 两个 EventLoopGroup
     *        bossGroup 只负责 Accept
     *        workerGroup 只负责 SocketChannel 的读写
     * 2. 如果有某些操作耗时眼中，可以再细分一个 专门负责耗时操作的 DefaultEventLoop
     *      在last方法指定这个耗时长的group执行， 这样可以避免耗时操作阻塞整个线程组
     *      通过 ctx.fireChannelRead 方法 可以将数据传递给下一个handler处理
     *
     * @param args
     */
    public static void main(String[] args) {
        // 1. 创建EventLoopGroup
        EventLoopGroup bossGroup = new NioEventLoopGroup();
        EventLoopGroup workerGroup = new NioEventLoopGroup();
        EventLoopGroup slowlyGroup = new DefaultEventLoopGroup();
        new ServerBootstrap()
                // bossGroup只负责Accept , workerGroup(默认CPU核心数*2)只负责SocketChannel的读写
                .group(bossGroup, workerGroup)
                .channel(NioServerSocketChannel.class)
                .childHandler(new ChannelInitializer<NioSocketChannel>() {
                    @Override
                    protected void initChannel(NioSocketChannel channel) throws Exception {
                        channel.pipeline()
                                .addLast("WorkerGroup",new ChannelInboundHandlerAdapter() {
                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        ByteBuf byteBuf = (ByteBuf) msg;
                                        log.debug("{}",byteBuf.toString(StandardCharsets.UTF_8));
                                        super.channelRead(ctx, msg);
                                        ctx.fireChannelRead(msg);
                                    }
                                })
                                .addLast(slowlyGroup, "SlowlyGroup", new ChannelInboundHandlerAdapter() {
                                    @Override
                                    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
                                        log.debug("耗时操作");
                                        ByteBuf byteBuf = (ByteBuf) msg;
                                        log.debug("Slowly Group : {}",byteBuf.toString(StandardCharsets.UTF_8));
                                        super.channelRead(ctx, msg);
                                    }
                                });
                    }
                })
                .bind(Const.PORT)
        ;
    }
}
